* Sep 19, 2007
* Gabor Antal
* detrend by groups

	
program DETREND
	version 9.2
	syntax varlist ,BY(varname) Time(varname) [DISplay Pre(string) Suf(string) DROP]

	/*SELECT REGRESSION SAMPLE*/
	
	quietly {
		regress `varlist' `time'
		tempvar esample
		gen `esample' = 1 if e(sample)
		
	/*SELECT FIRMS TO BE DETRENDED*/
	
		tempvar count
		bysort `by': egen `count' = count(`time') if `esample'==1
		tempvar todt
		gen `todt'=1 if `count'>=3 & `count'!=.
	
	/*DETREND*/
	
	}

	foreach v of varlist `varlist' {

		***FILL WITH ZERO DT VALUE THE TIME-INVARIANT FIRMS

		quietly {
			tempvar groups
			egen `groups' = group(`by') if `esample'==1
			sum `groups'
			local n=r(max)
			local N=r(N)

			tempvar falseid	
			egen `falseid' = group(`by') if `todt'==1
			sum `falseid'
			local k=r(max)       // #of groups to be eventually detrended (i.e. w/ at least 3 obs)
			local K=r(N)         // #of observations involved
		}

		if "`display'"=="display" {
			display ""
			display "CURRENT VARIABLE: `v'"
			display "TOTAL NUMBER OF GROUPS (w/ NON-MISSING OBS.): `n'"
			display "TOTAL NUMBER OF NON-MISSING OBSERVATIONS: `N'"
			display "NUMBER OF GROUPS TO BE DETRENDED (w/ AT LEAST 3 OBS.): `k'"
			display "NUMBER OF OBSERVATIONS INVOLVED: `K'"
			display ""
		}

		quietly {
			if "`pre'"!=""|"`suf'"!="" {
				gen `pre'`v'`suf' = 0 if `todt'!=1 & `esample'==1
			}
			else {
				gen _DT`v' = 0 if `todt'!=1 & `esample'==1
			}

			***DETREND REMAINING OBS
			
			sort `falseid' `time'
			tempvar maxt
			bysort `falseid': egen `maxt'=max(`time') if `todt'==1
			tempvar tmean
			bysort `falseid': egen `tmean'=mean(`time') if `todt'==1
			tempvar vmean
			bysort `falseid': egen `vmean'=mean(`v') if `todt'==1
			tempvar covvt
			bysort `falseid': gen `covvt'=sum((`v'-`vmean')*(`time'-`tmean')) if `todt'==1
			tempvar vart
			bysort `falseid': gen `vart'=sum((`time'-`tmean')^2) if `todt'==1
			tempvar help
			gen `help'=`covvt'/`vart' if `time'==`maxt' 
			tempvar beta_1
			bysort `falseid': egen `beta_1'=max(`help')
			macro drop help
			tempvar beta_0
			gen `beta_0'=`vmean'-`beta_1'*`tmean'

			if "`pre'"!=""|"`suf'"!="" {
				replace `pre'`v'`suf'=`v'-`beta_0'-`beta_1'*`time' if `todt'==1
			}
			else {
				replace _DT`v'=`v'-`beta_0'-`beta_1'*`time' if `todt'==1
			}

			if "`drop'"=="drop" {
				drop `v'
			}
			macro drop groups falseid maxt tmean vmean covvt vart beta_0 beta_1
		}
	}
end
